home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / editors / eedraw / src / eep / igraphep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-29  |  17.5 KB  |  553 lines

  1. /*****************************************************************************
  2. *   General routines to    handle the graphics.                     *
  3. *                                         *
  4. * Written by:  Gershon Elber                   Ver 0.1, Oct. 1989    *
  5. *                                         *
  6. * Support: Interface for the virtual device driver.                 *
  7. *****************************************************************************/
  8.  
  9. #define SUPPORT_GIF                 /* Dump it out as GIF file. */
  10.  
  11. #ifdef SUPPORT_GIF
  12. #include "gif_lib.h"
  13. #endif /* SUPPORT_GIF */
  14.  
  15. #include <stdio.h>
  16. #include "virtrstr.h"
  17. #include "program.h"
  18. #include "igraph.h"
  19.  
  20. /* #define DEBUG         Dump virtual screen to Hercules graphic device. */
  21.  
  22. #ifdef __MSDOS__
  23. #include <io.h>
  24. #include <fcntl.h>
  25. #include <bios.h>
  26. #include <dos.h>
  27. #include <conio.h>
  28. #endif /* __MSDOS__ */
  29.  
  30. #define EPSON_SIZE_X 1024
  31. #define EPSON_SIZE_Y 640
  32. #define EPSON_SIZE_MAX 1024            /* The maximum of the two above. */
  33. #define EPSON_SIZE_X2 (EPSON_SIZE_X / 2)
  34. #define EPSON_SIZE_Y2 (EPSON_SIZE_Y / 2)
  35.  
  36. /* The epson specific are defined here:                         */
  37. #define EPSON_WIDTH        80            /* 80 char per line. */
  38. #define EPSON_PIXEL_2_CHAR    8      /* 8 pixels per char, in REG_DENSITY. */
  39.  
  40. #define EPSON_ESC        "\x1b"        /* Actually regular escape char. */
  41. #define EPSON_RESET        "\x1b\x40"     /* Reset the printer - ESC @. */
  42. #define EPSON_VERTICAL_SPACE    "\x1b\x41\x08"   /* 8/72 vert. - ESC A 0x08. */
  43. #define EPSON_REG_DENSITY    "\x1b\x4b"   /* 640 pixels per 7.5" - ESC K. */
  44. #define EPSON_DUAL_DENSITY    "\x1b\x4c"  /* 1280 pixels per 7.5" - ESC L. */
  45.  
  46. static int GraphicMode = FALSE;
  47.  
  48. static void PutString(int DirectPrint, char *Str, int Len);
  49. static void PutString2(int DirectPrint, char *Str, int Len);
  50.  
  51. #ifdef __MSDOS__
  52. #ifdef DEBUG
  53. static void DisplayBufferOnHercules(void);
  54. static void HercGraphics(void);
  55. static void HercPutPoint(int x, int y);
  56. static void HercText(void);
  57. #endif /* DEBUG */
  58. #endif /* __MSDOS__ */
  59.  
  60. /****************************************************************************
  61. * Routine to reset all the system to starting condition    :            *
  62. ****************************************************************************/
  63. void IGInitGraph(void)
  64. {
  65.     if (!VirtInit(EPSON_SIZE_X, EPSON_SIZE_Y)) {
  66.     fprintf(stderr, "Failed to allocate virtual device (no memory).\n");
  67.     MyExit(1);
  68.     }
  69.     GraphicMode = TRUE;
  70. }
  71.  
  72. /****************************************************************************
  73. * Routine to close and shutdown    graphic    mode :                    *
  74. ****************************************************************************/
  75. void IGCloseGraph(void)
  76. {
  77.     if (GraphicMode) {
  78.     VirtClose();
  79.     GraphicMode = FALSE;
  80.     }
  81. }
  82.  
  83. /****************************************************************************
  84. * Routine to dump the screen to the desired output device.            *
  85. ****************************************************************************/
  86. void IGDumpScreen(OutputDriverType OutputKind, int DirectPrint,
  87.                         BooleanType DoubleDensity)
  88. {
  89. #ifdef SUPPORT_GIF
  90.     static GifColorType GifColorMap[] = { { 0, 0, 0 }, { 255, 255, 255 } };
  91.     GifFileType *GifFile;
  92. #endif /* SUPPORT_GIF */
  93.     int i, j, k, Count;
  94.     unsigned int Shift;
  95.     char LineBuffers[8][EPSON_SIZE_Y / 8 + 1], OutputBuffer[EPSON_SIZE_MAX],
  96.     LinePrefixLen[2];
  97.  
  98.     switch (OutputKind) {
  99.     case OUTPUT_EPSON:
  100.         if (DirectPrint != 0) break;
  101.  
  102. #ifdef __MSDOS__
  103.         /* Make sure stdout is output for binary output and buffer it. */
  104.         setmode(1, O_BINARY);
  105. #endif /* __MSDOS__ */
  106.         break;
  107. #ifdef SUPPORT_GIF
  108.     case OUTPUT_GIF:
  109.         if ((GifFile = EGifOpenFileHandle(1)) == NULL) {
  110.         fprintf(stderr, "Failed to open gif file.\n");
  111.         MyExit(-1);
  112.         }
  113.         break;
  114. #endif /* SUPPORT_GIF */
  115.     case OUTPUT_RAW:
  116. #ifdef __MSDOS__
  117.         /* Make sure stdout is output for binary output and buffer it. */
  118.         setmode(1, O_BINARY);
  119. #endif /* __MSDOS__ */
  120.         break;
  121.     default:
  122.         fprintf(stderr, "Output kind is not supported, exit.\n");
  123.         MyExit(-1);
  124.     }
  125.  
  126. #ifdef __MSDOS__
  127. #ifdef DEBUG
  128.     DisplayBufferOnHercules();
  129.     return;
  130. #endif /* DEBUG */
  131. #endif /* __MSDOS__ */
  132.  
  133.     switch (OutputKind) {
  134.     case OUTPUT_EPSON:
  135.         fprintf(stderr, "Dumping line [%d]:     ", EPSON_SIZE_X);
  136.  
  137.         /* Reset printer, and make sure no space between adjacent lines: */
  138.         PutString(DirectPrint, EPSON_RESET, 2);
  139.         PutString(DirectPrint, EPSON_VERTICAL_SPACE, 3);
  140.  
  141.         for (i = 0; i < EPSON_SIZE_X; i += 8) { /* Dump 8 lines at once: */
  142.         fprintf(stderr, "\b\b\b\b%-4d", i);
  143.  
  144.         for (j = 0; j <8; j++)
  145.             VirtGetBlock(i + j, 0, i + j, EPSON_SIZE_Y, LineBuffers[j]);
  146.  
  147.         Shift = 1;
  148.         Count = EPSON_SIZE_Y / 8;
  149.         for (j = 0; j < EPSON_SIZE_Y; j++) {
  150.             OutputBuffer[j] = 0;
  151.             for (k = 0; k < 8; k++) {
  152.             OutputBuffer[j] <<= 1;
  153.             if (LineBuffers[k][Count] & Shift) OutputBuffer[j]++;
  154.             }
  155.             if ((Shift <<= 1) == 256) {
  156.             Shift = 1;
  157.             Count--;
  158.             }
  159.         }
  160.         /* Find last position of non empty pixel byte: */
  161.         for (j = EPSON_SIZE_Y - 1; j >= 0; j--)
  162.             if (OutputBuffer[j] != 0) break;
  163.  
  164.         if (j != 0 || OutputBuffer[0] != 0) {
  165.             j++;
  166.             if (DoubleDensity) {
  167.             PutString(DirectPrint, EPSON_DUAL_DENSITY, 2);
  168.             LinePrefixLen[0] = (j * 2) % 256;
  169.             LinePrefixLen[1] = (j * 2) / 256;
  170.             PutString(DirectPrint, LinePrefixLen, 2);
  171.             PutString2(DirectPrint, OutputBuffer, EPSON_SIZE_Y);
  172.             }
  173.             else {
  174.             PutString(DirectPrint, EPSON_REG_DENSITY, 2);
  175.             LinePrefixLen[0] = j % 256;
  176.             LinePrefixLen[1] = j / 256;
  177.             PutString(DirectPrint, LinePrefixLen, 2);
  178.             PutString(DirectPrint, OutputBuffer, EPSON_SIZE_Y);
  179.             }
  180.         }
  181.         PutString(DirectPrint, "\x0d\x0a", 2);
  182.         }
  183.         break;
  184.     case OUTPUT_RAW:
  185.         fprintf(stderr, "Dumping line [%d]:     ", EPSON_SIZE_X);
  186.  
  187.         for (i = 0; i < EPSON_SIZE_X; i++) {
  188.         fprintf(stderr, "\b\b\b\b%-4d", i);
  189.         VirtGetBlock(i, 0, i, EPSON_SIZE_Y, LineBuffers[0]);
  190.         for (j = 0; j < EPSON_SIZE_Y / 8; j++)
  191.             putchar(LineBuffers[0][j]);
  192.         }
  193.         break;
  194. #ifdef SUPPORT_GIF
  195.     case OUTPUT_GIF:
  196.         fprintf(stderr, "Dumping line [%d]:     ", EPSON_SIZE_Y);
  197.  
  198.         if (EGifPutScreenDesc(GifFile, EPSON_SIZE_X, EPSON_SIZE_Y, 1, 0, 1,
  199.                            GifColorMap) == GIF_ERROR ||
  200.         EGifPutImageDesc(GifFile, 0, 0, EPSON_SIZE_X, EPSON_SIZE_Y,
  201.                         FALSE, 1, NULL) == GIF_ERROR) {
  202.         fprintf(stderr, "Failed to write to gif file.\n");
  203.         MyExit(-1);
  204.         }
  205.  
  206.         for (i = 0; i < EPSON_SIZE_Y; i++) {
  207.         fprintf(stderr, "\b\b\b\b%-4d", i);
  208.         VirtGetBlock(0, i, EPSON_SIZE_X, i, LineBuffers[0]);
  209.         Shift = 1;
  210.         Count = EPSON_SIZE_X / 8;
  211.         for (j = EPSON_SIZE_X; j >= 0; j--) {
  212.             OutputBuffer[j] = (LineBuffers[0][Count] & Shift) != 0;
  213.             if ((Shift <<= 1) == 256) {
  214.             Shift = 1;
  215.             Count--;
  216.             }
  217.         }
  218.         if (EGifPutLine(GifFile, (GifPixelType *) OutputBuffer,
  219.                          EPSON_SIZE_X) == GIF_ERROR) {
  220.             fprintf(stderr, "Failed to write to gif file.\n");
  221.             MyExit(-1);
  222.         }
  223.         }
  224.         if (EGifCloseFile(GifFile) == GIF_ERROR) {
  225.         fprintf(stderr, "Failed to close gif file.\n");
  226.         MyExit(-1);
  227.         }
  228.         break;
  229. #endif /* SUPPORT_GIF */
  230.     }
  231. }
  232.  
  233. /******************************************************************************
  234. * Dumps the string of given length, to Prt. No char in Str has special          *
  235. * meaning, and even zero (NULL) chars are dumped.                  *
  236. * If however DirectPrint is non zero, string is dumped to specifed lpt port.  *
  237. ******************************************************************************/
  238. static void PutString(int DirectPrint, char *Str, int Len)
  239. {
  240.     int i;
  241.  
  242.     if (DirectPrint != 0) {
  243. #ifdef __MSDOS__
  244.     for (i = 0; i < Len; i++) biosprint(0, Str[i], DirectPrint - 1);
  245. #else
  246.     fprintf(stderr, "Output kind is not supported, exit.\n");
  247.     MyExit(-1);
  248. #endif /* __MSDOS__ */
  249.     }
  250.     else
  251.     fwrite(Str, Len, 1, stdout);
  252. }
  253.  
  254. /******************************************************************************
  255. * Dumps the string of given length, to Prt. No char in Str has special          *
  256. * meaning, and even zero (NULL) chars are dumped. Every char is dumped twice. *
  257. * If however DirectPrint is non zero, string is dumped to specifed lpt port.  *
  258. ******************************************************************************/
  259. static void PutString2(int DirectPrint, char *Str, int Len)
  260. {
  261.     int i;
  262.  
  263.     if (DirectPrint != 0) {
  264. #ifdef __MSDOS__
  265.     for (i = 0; i < Len; i++) {
  266.         biosprint(0, Str[i], DirectPrint - 1);
  267.         biosprint(0, Str[i], DirectPrint - 1);
  268.     }
  269. #else
  270.     fprintf(stderr, "Output kind is not supported, exit.\n");
  271.     MyExit(-1);
  272. #endif /* __MSDOS__ */
  273.     }
  274.     else {
  275.     for (i = 0; i < Len; i++) {
  276.         putchar(Str[i]);
  277.         putchar(Str[i]);
  278.     }
  279.     }
  280. }
  281.  
  282.  
  283. /****************************************************************************
  284. * Routine to map drawing x coordinate into screen space.            *
  285. ****************************************************************************/
  286. int IGMapX(int x)
  287. {
  288.     return x >> IG_DEFAULT_ZOOM_FACTOR;
  289. }
  290.  
  291. /****************************************************************************
  292. * Routine to map drawing y coordinate into screen space.            *
  293. ****************************************************************************/
  294. int IGMapY(int y)
  295. {
  296.     return y >> IG_DEFAULT_ZOOM_FACTOR;
  297. }
  298.  
  299. /****************************************************************************
  300. * Routine to move to a new position, as in Drawing space.            *
  301. ****************************************************************************/
  302. void IGMoveTo(int x, int y)
  303. {
  304.     VirtMoveTo(IGMapX(x), IGMapY(y));
  305. }
  306.  
  307. /****************************************************************************
  308. * Routine to draw to a new position, as in Drawing space.            *
  309. ****************************************************************************/
  310. void IGLineTo(int x, int y)
  311. {
  312.     VirtLineTo(IGMapX(x), IGMapY(y));
  313. }
  314.  
  315. /****************************************************************************
  316. * Routine to draw a line between the two given points.                *
  317. ****************************************************************************/
  318. void IGLine(int x1, int y1, int x2, int y2)
  319. {
  320.     VirtMoveTo(IGMapX(x1), IGMapY(y1));
  321.     VirtLineTo(IGMapX(x2), IGMapY(y2));
  322. }
  323.  
  324. /****************************************************************************
  325. * Routine to draw a new polyline and fill it if Fill.                *
  326. ****************************************************************************/
  327. void IGPoly(int n, int *Points, int Fill)
  328. {
  329.     int i;
  330.     static PrintedWarning = FALSE;
  331.  
  332.     VirtMoveTo(IGMapX(Points[0]), IGMapY(Points[1]));
  333.     for (i = 1; i < n; i++) {
  334.     VirtLineTo(IGMapX(Points[i * 2]), IGMapY(Points[i * 2 + 1]));
  335.     }
  336.     if (Fill) {
  337.     if (!PrintedWarning) {
  338.         fprintf(stderr, "Warning: polygon fill not supported - ignored.\n");
  339.         PrintedWarning = TRUE;
  340.     }
  341.     }
  342. }
  343.  
  344. /****************************************************************************
  345. * Routine to draw a bar, as in Drawing space.                    *
  346. ****************************************************************************/
  347. void IGBar(int x1, int y1, int x2, int y2)
  348. {
  349.     VirtBar(IGMapX(x1), IGMapY(y1), IGMapX(x2), IGMapY(y2));
  350. }
  351.  
  352. /****************************************************************************
  353. * Routine to draw a circle, as in Drawing space.                *
  354. ****************************************************************************/
  355. void IGCircle(int x, int y, int r)
  356. {
  357.     VirtCirc(IGMapX(x), IGMapY(y), r >> IG_DEFAULT_ZOOM_FACTOR);
  358. }
  359.  
  360. /****************************************************************************
  361. * Routine to draw an arc, as in Drawing space.                    *
  362. * As the Y axes is inverted the Angles should be inverted as well.        *
  363. ****************************************************************************/
  364. void IGArc(int x, int y, int StAngle, int EndAngle, int r)
  365. {
  366.     VirtArc(IGMapX(x), IGMapY(y), r >> IG_DEFAULT_ZOOM_FACTOR,
  367.                             StAngle, EndAngle);
  368. }
  369.  
  370. /****************************************************************************
  371. * Routine to draw the given text in current cursor position.            *
  372. ****************************************************************************/
  373. void IGText(char *s)
  374. {
  375.     VirtText(s);
  376. }
  377.  
  378. /****************************************************************************
  379. * Routine to draw the not bar above a negated text.                *
  380. ****************************************************************************/
  381. void IGDrawNotBar(int x1, int y1, int x2, int y2, char *Str)
  382. {
  383.     IGMoveToNoMap(x1, y1);
  384.     IGLineRelToNoMap(x2, y2);
  385. }
  386.  
  387. /****************************************************************************
  388. * Routine to set attributes - horiz./vert. and centering.            *
  389. ****************************************************************************/
  390. void IGTextFormat(TextOrientationType Orient, int Scale,
  391.           TextHorizJustifyType XCenter, TextVertJustifyType YCenter)
  392. {
  393.     VirtTextFormat(Orient, Scale, XCenter, YCenter);
  394. }
  395.  
  396. /****************************************************************************
  397. * Routine to set color to color within range.                    *
  398. ****************************************************************************/
  399. void IGSetColor(int Color)
  400. {
  401.     VirtSetColor(Color);
  402. }
  403.  
  404. /*****************************************************************************
  405. *   Routine to clear all the screen.                         *
  406. *****************************************************************************/
  407. void IGClearAllScreen(void)
  408. {
  409.     VirtClear();
  410. }
  411.  
  412. /*****************************************************************************
  413. *   Relative line to in screen coordinates.                     *
  414. *****************************************************************************/
  415. void IGLineRelToNoMap(int x, int y)
  416. {
  417.     VirtLineRelTo(x, y);
  418. }
  419.  
  420. /*****************************************************************************
  421. *   Move to in screen coordinates.                         *
  422. *****************************************************************************/
  423. void IGMoveToNoMap(int x, int y)
  424. {
  425.     VirtMoveTo(x, y);
  426. }
  427.  
  428. /*****************************************************************************
  429. *   Line in screen coordinates.                             *
  430. *****************************************************************************/
  431. void IGLineNoMap(int x1, int y1, int x2, int y2)
  432. {
  433.     VirtLine(x1, y1, x2, y2);
  434. }
  435.  
  436. /*****************************************************************************
  437. *   Returns text width in screen coordinates.                     *
  438. *****************************************************************************/
  439. int IGTextWidthNoMap(char *s)
  440. {
  441.     return VirtTextWidth(s);
  442. }
  443.  
  444. /*****************************************************************************
  445. *   Returns text height in screen coordinates.                     *
  446. *****************************************************************************/
  447. int IGTextHeightNoMap(char *s)
  448. {
  449.     return VirtTextHeight(s);
  450. }
  451.  
  452. #ifdef __MSDOS__
  453. #ifdef DEBUG
  454.  
  455. /******************************************************************************
  456. * This routine fetch the vitual frame buffer content and display it on an     *
  457. * hercules device.                                  *
  458. ******************************************************************************/
  459. static void DisplayBufferOnHercules(void)
  460. {
  461.     int i, j, Shift, MaxX, MaxY;
  462.     char ScanLine[256], *p;
  463.  
  464.     MaxX = EPSON_SIZE_X;
  465.     if (MaxX > 720 * 2) MaxX = 720 * 2;
  466.     MaxY = EPSON_SIZE_Y;
  467.     if (MaxY > 350 * 2) MaxY = 350 * 2;
  468.  
  469.     HercGraphics();
  470.  
  471.     for (i = 0; i < MaxX; i += 2) {
  472.     VirtGetBlock(i, 0, i, MaxY - 1, ScanLine);
  473.     p = ScanLine;
  474.     Shift = 256;
  475.     for (j = 0; j < MaxY; j++) {
  476.         if (Shift == 1) {
  477.         Shift = 256;
  478.         p++;
  479.         }
  480.         if (((*p) & (Shift >>= 1)) != 0)
  481.         HercPutPoint(i >> 1, j >> 1);
  482.     }
  483.     }
  484.  
  485.     sound(1000);
  486.     delay(100);
  487.     nosound();
  488.  
  489.     getch();
  490.  
  491.     HercText();
  492. }
  493.  
  494. /******************************************************************************
  495. * Go to hercules graphic mode, page 1, and clear the screen.              *
  496. ******************************************************************************/
  497. static void HercGraphics(void)
  498. {
  499.     static int far *HerculesScreen = MK_FP(0xb000, 0x0000);
  500.     static unsigned char GraphModeRegs[] =
  501.     { 53,45,46, 8,91, 2,87,87, 2, 3, 0, 0, 0, 0, 0, 0 };
  502.     int i;
  503.  
  504.     outportb(0x3bf, 0x01);
  505.     outportb(0x3b8, 0x00);
  506.  
  507.     for (i=0; i<12; i++) {
  508.     outportb(0x3b4, i);
  509.     outportb(0x3b5, GraphModeRegs[i]);
  510.     }
  511.  
  512.     outportb(0x3b8, 0x2a);
  513.  
  514.     for (i=0; i<16384; i++) HerculesScreen[i] = 0x0000;
  515. }
  516.  
  517. /******************************************************************************
  518. * Plot one point at x, y on the hercules page 1 screen.                  *
  519. ******************************************************************************/
  520. static void HercPutPoint(int x, int y)
  521. {
  522.     static char far *HerculesScreen = MK_FP(0xb000, 0x0000);
  523.     int Bit = x & 0x07, Byte = x >> 3, Page = y & 0x03, PageY = y >> 2;
  524.  
  525.     HerculesScreen[Page * 0x2000 + PageY * 90 + Byte] |= 128 >> Bit;
  526. }
  527.  
  528. /******************************************************************************
  529. * Go to hercules text mode.                              *
  530. ******************************************************************************/
  531. static void HercText(void)
  532. {
  533.     static int far *HerculesScreen = MK_FP(0xb000, 0x0000);
  534.     static unsigned char TextModeRegs[] =
  535.     { 97,80,82,15,25, 6,25,25, 2,13,11,12, 0, 0, 0, 0 };
  536.     int i;
  537.  
  538.     outportb(0x3bf, 0x01);
  539.     outportb(0x3b8, 0x00);
  540.  
  541.     for (i=0; i<12; i++) {
  542.     outportb(0x3b4, i);
  543.     outportb(0x3b5, TextModeRegs[i]);
  544.     }
  545.  
  546.     outportb(0x3b8, 0x28);
  547.  
  548.     for (i=0; i<16384; i++) HerculesScreen[i] = 0x0720;
  549. }
  550.  
  551. #endif /* DEBUG */
  552. #endif /* __MSDOS__ */
  553.